package service

import (
	"fmt"
	"strings"

	assetapi "github.com/hyperledger/fabric-samples/asset-kx/chaincode-go/chaincode/asset/api"
	assetruleapi "github.com/hyperledger/fabric-samples/asset-kx/chaincode-go/chaincode/assetrule/api"
	ledgerapi "github.com/hyperledger/fabric-samples/asset-kx/chaincode-go/chaincode/ledger-api"
)

type AssetRuleSupport struct {
	AssetRuleContractApi assetruleapi.AssetRuleContractApi `inject:"AssetRuleContractApi"`
}

func (a AssetRuleSupport) ValuateAsset(ctx ledgerapi.TransactionContextInterface, assetFromDb assetapi.Asset, assetRuleContent string) (string, error) {
	var assetRule *assetruleapi.AssetRule
	if strings.TrimSpace(assetRuleContent) == "" {
		assetRules, err := a.AssetRuleContractApi.ReadAssetRules(ctx, assetFromDb.GetAssetType(), assetruleapi.RULE_TYPE_ASSET_VALUATION)
		if err != nil {
			return "", err
		}
		if len(assetRules) == 0 {
			return "", fmt.Errorf("can not find asset valuation rule by assetNo[%s], ruleType[%s]", assetFromDb.GetAssetNo(), assetruleapi.RULE_TYPE_ASSET_VALUATION)
		}
		assetRule = assetRules[0]
	} else {
		var err error
		assetRule, err = assetruleapi.Unmarshal([]byte(assetRuleContent))
		if err != nil {
			return "", err
		}
	}
	if evaluator, found := ruleCalculator[assetFromDb.GetAssetType()][assetRule.RuleExpression]; found {
		valuationAmount, err := evaluator(assetFromDb, assetRule)
		if err != nil {
			return "", err
		}
		return valuationAmount.(string), nil
	}
	return "", fmt.Errorf("can not find asset valuation evaluator by AssetType[%s], RuleExpression[%s]", assetFromDb.GetAssetType(), assetRule.RuleExpression)
}
